package com.bm.dao;


import com.bm.pojo.relationship.GrapeAddrRelationship;
import com.bm.pojo.sort.GrapeSort;
import com.sun.org.apache.bcel.internal.generic.RETURN;
import lombok.extern.java.Log;
import lombok.val;
import org.neo4j.driver.*;
import org.neo4j.driver.types.Node;
import org.neo4j.driver.types.Relationship;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;


@Component
public class Neo4jIndexDao {
    private static Driver driver;

    @Autowired
    public Neo4jIndexDao(Driver driver) {
        Neo4jIndexDao.driver = driver;
    }

    public List setSession(String cql){
        try {
            Session session = driver.session();
            StatementResult result = session.run(cql);
            List<Record> list = result.list();
            return list;
        } catch (Exception e) {
        e.printStackTrace();
    }
        return null;

    }

    /**
     * cql的return返回多种节点match (n)-[edge]-(n) return n,m,edge：限定返回关系时，关系的别名必须“包含”edge
     * @param cql 查询语句
     * @return List<Map<String,Object>>
     */
    public HashMap  getList(String cql) {

        HashMap<String, List> hashMap = new HashMap<>();
        try {
            Session session = driver.session();
            StatementResult result = session.run(cql);
            List<Record> list = result.list();
            List<Object> nodes = new ArrayList<>();
            List<GrapeAddrRelationship> links = new ArrayList<>();
            for (Record r : list) {
                //GrapeSort grapeSort = (GrapeSort)r.get(0);
                Value nodeGrape = r.get(0);
                Node node1 = r.get(0).asNode();
                Map<String, Object> nodeMap = node1.asMap();
                GrapeSort start = new GrapeSort();
                start.setGrapeName((String)nodeMap.get("grapeName"));
                start.setDetails((String)nodeMap.get("details"));
                start.setId(node1.id());


                Relationship relationship1 = r.get(1).asRelationship();
                GrapeAddrRelationship relationship = new GrapeAddrRelationship();
                relationship.setSource(relationship1.startNodeId());
                relationship.setTarget(relationship1.endNodeId());
                relationship.setAddr(relationship1.type());


                Value nodeArea = r.get(2);
                //ProducingArea producingArea = (ProducingArea) r.get(2);

                Node node2 = r.get(2).asNode();
                Map<String, Object> nodeMap1 = node2.asMap();
                GrapeSort end = new GrapeSort();
                end.setGrapeName((String)nodeMap1.get("name"));
                end.setDetails((String)nodeMap1.get("details"));
                end.setId(node2.id());
                nodes.add(start);
                nodes.add(end);
                links.add(relationship);

            }
            hashMap.put("nodes",nodes);
            hashMap.put("links",links);

            return hashMap;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return hashMap;
    }


    /**
     * 查询全文检索数据,获取检索到的节点
     * @param query 传入的查询词
     */
    public StatementResult getIndexNode(String query,double jingDu){
        String cql = "CALL db.index.fulltext.queryNodes(\"grapeIndex\", \""+query+"\") YIELD node, score\n" +
                "where score>"+jingDu+"\n" +
                "RETURN node,score";
        StatementResult result = null;
        try {
            Session session = driver.session();
            result = session.run(cql);
        }catch (Exception e){
           e.getMessage();

        }finally {
            return result;
        }

    }

    /**
     * 跟据检索根节点获取子节点
     * @param node
     * @return
     */
    public List<Record> getNodeToRetrieve(Map node){
        String name="name";
        if("grapeTu".equals(node.get("label"))){
            name="grapeName";
        }
        String cql="match (n:"+node.get("label")+"{"+name+":\""+node.get("name")+"\"})-[r]-(m) return n,r,m";
        List<Record> list = setSession(cql);
        if(list.size()>0 && list!=null){
            return list;
        }else {
            return null;
        }
    }


    /**
     *
     * @param query 要查询的分类
     * @param label node label名
     * @param name
     * @return
     */
    public  List<Record>  getSortList(String query, String label, String name){

        String cql="match (n:"+label+"{"+name+":\""+query+"\"})-[r]-(m) return n,r,m";

        List<Record> list = setSession(cql);
        if(list.size()>0 && list!=null){
            return list;
        }else {
            return null;
        }

    }

    /**
     * 获取所有节点及关系
     * @return
     */
    public  HashMap<String, List<Record>>  getAll(){

        String cql="MATCH (n) RETURN n";
        String cql1="MATCH (n)-[r]->() RETURN r";
        List<Record> list1 = setSession(cql1);
        List<Record> list = setSession(cql);
        HashMap<String, List<Record>> stringListHashMap = new HashMap<>();
        stringListHashMap.put("nodes",list);
        stringListHashMap.put("links",list1);

        if(stringListHashMap.size()>0 && stringListHashMap!=null){
            return stringListHashMap;
        }else {
            return null;
        }

    }

    /**
     * 相似度判断
     * @param name
     * @return
     */
    public Boolean getSimilarity(String name){
        boolean flag=false;
        String cql = "CALL db.index.fulltext.queryNodes(\"grapeIndex2\", \""+name+"\") YIELD node, score\n" +
                "    RETURN score";
        List<Record> list = setSession(cql);
        if(list.size()==0){
            return flag;
        }
        // 获取最大的相似度
        Value value = list.get(0).values().get(0);
        double similarity = value.asDouble();
        if(similarity>0.9){ //true 节点已经存在
            flag=true;
        }

        return flag;
    }

    /**
     * 添加关系
     * @param nid
     * @param pid
     * @param label
     * @return
     */
    public boolean addLink(Integer nid,Integer pid,String label){
        boolean flag = false;
        String cql = "MATCH(n),(p) where id(n)="+nid+" and id(p)="+pid+" \n" +
                "create (p)-[r:`"+label+"`]->(n)\n" +
                " RETURN n,r,p LIMIT 25";
        List list = setSession(cql);
        if(list.size()>0){
            flag = true;
        }
        return flag;
    }






}